package OrderRefundService

import (
	"context"
	"errors"
	"gdshop-admin-go-api/app/entity"
	"gdshop-admin-go-api/app/request/BaseReq"
	"gdshop-admin-go-api/app/service/OrderService"
	"gdshop-admin-go-api/library/response"
	toolsDb "gdshop-admin-go-api/library/tools/db"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
)

// 退款
func Refund(r *ghttp.Request, req *BaseReq.I) *response.JsonResponse {
	ctx := r.GetCtx()
	var orModel *entity.OrderRefund
	err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "order_refund").
		Where("status = 3 AND order_sub_id = ?", req.Id).Struct(&orModel)
	if err != nil {
		return response.FailByRequestMessage(r, "找不到退货信息")
	}
	if orModel.Status != 3 {
		return response.FailByRequestMessage(r, "当前状态不允许退款")
	}

	// 判断，如果只有一个子订单，则关闭订单
	/*osCount, err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "order_sub").Fields(1).
		Where("order_id", orModel.OrderId).Count()
	if err != nil {
		return nil
	}
	*/
	var oModel *entity.Order
	err = toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "order").Where("id", orModel.OrderId).Struct(&oModel)
	if err != nil {
		return response.FailByRequestMessage(r, err.Error())
	}
	if oModel == nil {
		return response.FailByRequestMessage(r, "找不到订单数据")
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		update, err := tx.Model("order_refund").Unscoped().Where("id", orModel.Id).
			Update(g.Map{
				"status": 99,
			})
		if err != nil {
			return err
		}
		affected, err := update.RowsAffected()
		if err != nil {
			return err
		}
		if affected < 1 {
			return errors.New("更新失败01")
		}
		update, err = tx.Model("order_sub").Unscoped().
			Where("id", orModel.OrderSubId).Update(g.Map{
			"refund_status": 99,
		})
		affected, err = update.RowsAffected()
		if err != nil {
			return err
		}
		if affected < 1 {
			return errors.New("更新失败02")
		}

		err = OrderRefundBackPrice(tx, orModel, req.AdminId)
		if err != nil {
			return err
		}

		// 判断，如果只有一个子订单，并且退款金额是全部，则关闭订单
		/*if osCount < 2 {

		}*/
		// 如果完全退款，关闭订单，如果部分退款，不理会状态
		if oModel.TotalPrice == orModel.ApplyMoney {
			err := refundCloseOrder(tx, oModel, req.AdminId)
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		return response.FailByRequestMessage(r, err.Error())
	}

	return response.SuccessByRequestMessage(r, "发起退款成功")
}

func OrderRefundBackPrice(tx *gdb.TX, orModel *entity.OrderRefund, opAdminId int) error {
	orderNO, err := tx.Model("order").Where("id", orModel.OrderId).
		Fields("order_no").Value("order_no")
	if err != nil {
		return err
	}
	/*var oplList []*entity.OrderPayLog
	err = tx.Model("order_pay_log").Where("order_id", orModel.OrderId).Structs(&oplList)
	if err != nil {
		return err
	}

	var tmpMoney int64
	// 应退金额
	mustBackMoney := orModel.ApplyMoney
	for _, item := range oplList {
		// 应退金额小于，说明退完了
		if mustBackMoney < 1 {
			break
		}
		// 应退 金额 大于等于 当前支付
		if mustBackMoney >= item.Money {
			tmpMoney = item.Money
		} else {
			// 应退金额 不足当前
			tmpMoney = mustBackMoney
		}
		// ApplyId 只有申请人才能操作自己的订单
		err := OrderService.BackOrderPriceTx(tx, orModel.ApplyId, orModel.OrderId,
			gconv.Int(tmpMoney), item.PaymentMethod, "售后退款，订单ID："+orderNO.String(),
			opAdminId, 0)
		if err != nil {
			return err
		}
		// 退款成功，已退加上退款成功金额
		mustBackMoney -= tmpMoney
	}
	// 还有未退完的金额
	if mustBackMoney > 1 {
		return errors.New("退款失败")
	}*/

	err = OrderService.OrderBackPriceTx(tx, orModel.OrderId, orModel.ApplyMoney, orModel.ApplyId, opAdminId,
		0, "售后退款，订单ID："+orderNO.String())
	if err != nil {
		return err
	}

	return nil
}

// 退款关闭订单
func refundCloseOrder(tx *gdb.TX, oModel *entity.Order, AdminId int) error {
	newData := g.Map{
		"status": 0,
	}
	_, err := tx.Model("order").Where("id", oModel.Id).Update(newData)
	if err != nil {
		return err
	}
	_, err = tx.Model("order_sub").Where("order_id", oModel.Id).Update(newData)
	if err != nil {
		return err
	}
	// 退还库存
	err = OrderService.BackGoodsStock(tx, oModel)
	if err != nil {
		return err
	}
	// 写日志
	err = OrderService.InsertOrderLog(tx, g.Map{
		"type":      "close_order",
		"order_id":  oModel.Id,
		"admin_id":  AdminId,
		"member_id": 0,
		"old_data": g.Map{
			"status": oModel.Status,
		},
		"new_data": newData,
	})
	if err != nil {
		return err
	}

	return nil
}
